package com.kuangjia.student_ems.service.impl;

import com.kuangjia.student_ems.dto.DepartmentDTO;
import com.kuangjia.student_ems.dto.request.DepartmentRequest;
import com.kuangjia.student_ems.entity.Department;
import com.kuangjia.student_ems.exception.ResourceNotFoundException;
import com.kuangjia.student_ems.repository.DepartmentRepository;
import com.kuangjia.student_ems.service.DepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kuangjia.student_ems.repository.DepartmentMapper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DepartmentServiceImpl implements DepartmentService {
    
    private final DepartmentRepository departmentRepository;
    @Autowired
    private DepartmentMapper departmentMapper;
    
    @Autowired
    public DepartmentServiceImpl(DepartmentRepository departmentRepository) {
        this.departmentRepository = departmentRepository;
    }
    
    @Override
    @Transactional
    public DepartmentDTO createDepartment(DepartmentRequest request) {
        if (departmentRepository.existsByName(request.getName())) {
            throw new IllegalArgumentException("部门名称已存在");
        }
        
        Department department = new Department();
        department.setName(request.getName());
        department.setDescription(request.getDescription());
        
        Department savedDepartment = departmentRepository.save(department);
        return convertToDTO(savedDepartment);
    }
    
    @Override
    @Transactional
    public DepartmentDTO updateDepartment(Long departmentId, DepartmentRequest request) {
        Department department = departmentRepository.findById(departmentId)
                .orElseThrow(() -> new ResourceNotFoundException("部门", "id", departmentId));
        
        // 检查名称是否已存在，但忽略当前部门
        if (!department.getName().equals(request.getName()) && departmentRepository.existsByName(request.getName())) {
            throw new IllegalArgumentException("部门名称已存在");
        }
        
        department.setName(request.getName());
        department.setDescription(request.getDescription());
        
        Department updatedDepartment = departmentRepository.save(department);
        return convertToDTO(updatedDepartment);
    }
    
    @Override
    @Transactional
    public void deleteDepartment(Long departmentId) {
        if (!departmentRepository.existsById(departmentId)) {
            throw new ResourceNotFoundException("部门", "id", departmentId);
        }
        departmentRepository.deleteById(departmentId);
    }
    
    @Override
    public DepartmentDTO getDepartmentById(Long departmentId) {
        Department department = departmentRepository.findById(departmentId)
                .orElseThrow(() -> new ResourceNotFoundException("部门", "id", departmentId));
        return convertToDTO(department);
    }
    
    @Override
    public List<DepartmentDTO> getAllDepartments() {
        List<Department> departments = departmentRepository.findAll();
        return departments.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public DepartmentDTO getDepartmentByName(String name) {
        Department department = departmentRepository.findByName(name)
                .orElseThrow(() -> new ResourceNotFoundException("部门", "name", name));
        return convertToDTO(department);
    }
    
    @Override
    public boolean existsByName(String name) {
        return departmentRepository.existsByName(name);
    }
    
    @Override
    public List<Map<String, Object>> getDepartmentsWithEmployeeCount() {
        List<Object[]> results = departmentRepository.getDepartmentsWithEmployeeCount();
        List<Map<String, Object>> departmentsWithCount = new ArrayList<>();
        
        for (Object[] result : results) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", result[0]);
            map.put("name", result[1]);
            map.put("employeeCount", result[2]);
            departmentsWithCount.add(map);
        }
        
        return departmentsWithCount;
    }
    
    @Override
    public List<DepartmentDTO> searchDepartments(String keyword) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return getAllDepartments();
        }
        
        String searchTerm = "%" + keyword.toLowerCase() + "%";
        List<Department> departments = departmentRepository.findByNameContainingIgnoreCaseOrDescriptionContainingIgnoreCase(searchTerm, searchTerm);
        return departments.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public IPage<DepartmentDTO> getDepartmentPage(Page<Department> page, String keyword) {
        try {
            QueryWrapper<Department> wrapper = new QueryWrapper<>();
            if (keyword != null && !keyword.isEmpty()) {
                wrapper.lambda().like(Department::getName, keyword)
                    .or().like(Department::getDescription, keyword);
            }
            wrapper.lambda().orderByAsc(Department::getId);
            IPage<Department> departmentPage = departmentMapper.selectPage(page, wrapper);
            IPage<DepartmentDTO> dtoPage = departmentPage.convert(this::convertToDTO);
            return dtoPage;
        } catch (Exception e) {
            System.err.println("部门分页查询异常: " + e.getMessage());
            e.printStackTrace();
            throw e;
        }
    }
    
    private DepartmentDTO convertToDTO(Department department) {
        DepartmentDTO dto = new DepartmentDTO();
        dto.setId(department.getId());
        dto.setName(department.getName());
        dto.setDescription(department.getDescription());
        dto.setEmployeeCount(department.getUsers().size());
        dto.setCreateTime(department.getCreateTime());
        dto.setUpdateTime(department.getUpdateTime());
        return dto;
    }
} 